/**
 * Created by chenlei on 14-12-20.
 */
package {


import GameObject.Bomb;
import GameObject.Bullet;
import GameObject.Enemy;
import GameObject.Hero;

import Qbase.utils.calculate.QFileUtil;
import Qbase.utils.sound.SoundManager;

import feathers.controls.TextInput;


import flash.desktop.NativeApplication;
import flash.events.Event;
import flash.filesystem.File;
import flash.geom.Point;
import flash.media.SoundTransform;
import flash.net.URLLoader;
import flash.ui.Multitouch;

import lzm.starling.STLConstant;
import lzm.starling.STLRootClass;
import lzm.starling.swf.Swf;
import lzm.starling.swf.SwfAssetManager;
import lzm.starling.swf.display.SwfButton;
import lzm.starling.swf.display.SwfSprite;


import starling.core.Starling;
import starling.display.DisplayObject;
import starling.display.Image;
import starling.display.MovieClip;
import starling.events.Event;
import starling.events.Touch;
import starling.events.TouchEvent;
import starling.events.TouchPhase;
import starling.text.TextField;
import starling.textures.TextureSmoothing;
import starling.utils.Color;


import utils.Kit;

public class GameRoot extends STLRootClass {

    //缓存临时对象
    private var tempVector:Vector.<Object> = null;
    //hero obj
    private var hero:Hero = null;


    public function GameRoot() {
        super();
        Swf.init(this);

        if (stage) {
            init();
        } else {
            //init
            addEventListener(starling.events.Event.ADDED_TO_STAGE, init);    //init sprite container
        }

        //获取焦点
        NativeApplication.nativeApplication.addEventListener(flash.events.Event.ACTIVATE, function (e:flash.events.Event):void {
            SoundManager.getInstance().pause();
            Starling.current.start();
        });
        //失去焦点
        NativeApplication.nativeApplication.addEventListener(flash.events.Event.DEACTIVATE, function (e:flash.events.Event):void {
            if (Multitouch.supportsTouchEvents) {
                SoundManager.getInstance().pause();
                Starling.current.stop();
            }
        });


    }


    /**
     * 初始化游戏资源
     * @param event
     */
    private function init():void {
        GameSystem.swfAssetManager = new SwfAssetManager();
        GameSystem.swfAssetManager.verbose = true;
        GameSystem.assetManager = GameSystem.swfAssetManager.otherAssets;
        GameSystem.root = this;
        /**
         * 加载资源
         */
        GameSystem.swfAssetManager
                .enqueue("test", [new File(File.applicationDirectory.url + "test")]);

        GameSystem.swfAssetManager
                .enqueueOtherAssets(QFileUtil
                        .getAllFileUrlByDirectory(GameConstants.filePath, "shoot", ["png", "xml"]));

        GameSystem.swfAssetManager.loadQueue(function (currentRatio:Number):void {

            if (currentRatio == 1) {
                //done
                removeEventListener(starling.events.Event.ADDED_TO_STAGE, init);


                //add bg
                var bg_sprite:SwfSprite = GameSystem.swfAssetManager.getSwf("test").createSprite("spr_bg");
                bg_sprite.width = STLConstant.StageWidth;
                bg_sprite.height = STLConstant.StageHeight;
                addChild(bg_sprite);
                bg_sprite.getButton("startGame").addEventListener(TouchEvent.TOUCH, startGame);


//                var usernameTable:TextInput = new TextInput();
//                usernameTable.width = 270;
//                usernameTable.height = 40;
//                //设置输入文本属性
//                usernameTable.textEditorProperties.color = Color.WHITE;
//                usernameTable.textEditorProperties.fontSize = 30;
//                usernameTable.textEditorProperties.border = true;
//                usernameTable.text = "输入用户名";  //defualt value
//                usernameTable.clearFocus();
//                var point:Point = Kit.midPoint(usernameTable);
//                usernameTable.x = point.x;
//                usernameTable.y = point.y;
//                bg_sprite.addChild(usernameTable);


                // test   UI
                //addChild(TestFeathers.testList())


            }
        });
    }


    /**
     * 动画测试
     */
    private function loading():void {
        var mc_loading:MovieClip = new MovieClip(GameSystem.assetManager.getTextures("game_loading"));
        mc_loading.fps = 4;
        mc_loading.x =
                (STLConstant.StageWidth - mc_loading.width) / 2;
        mc_loading.y =
                (STLConstant.StageHeight - mc_loading.height) / 2;

        addChild(mc_loading);

        Starling.juggler.add(mc_loading);

            mc_loading.addEventListener(starling.events.Event.COMPLETE,
                    function (e:starling.events.Event):void {
                Starling.juggler.remove(mc_loading);
                removeChild(e.currentTarget as MovieClip);
        });

    }


    /**
     * 开始游戏
     */
    public function startGame(touchEvent:TouchEvent):void {
        var touch:Touch = touchEvent.getTouch(touchEvent.currentTarget as DisplayObject, TouchPhase.ENDED);
        if (touch) {
            (touchEvent.currentTarget as DisplayObject).removeEventListener(TouchEvent.TOUCH, startGame);
            loading();

            SoundManager.getInstance().playSound("sound/button.mp3");

            Starling.juggler.delayCall(function ():void {
                //添加移动背景
                GameSystem.root.addBgAndMove();

                //创建hero
                GameSystem.root.createHero();

                //play sound
                var transform:SoundTransform = new SoundTransform();
                transform.volume = 1;
                SoundManager.getInstance().playMusic("sound/game_music.mp3");

                //add enemy
                EnemyManager.getInstance().start(GameSystem.root);

                // add some button
                GameSystem.root.addEventListener(starling.events.Event.ENTER_FRAME, startGame0);

            }, 1);

        }

    }

    private function startGame0():void {

        checkObjStatus();

        clearObj();
    }


    /**
     * 添加游戏移动背景
     * 并移动
     */
    private var testAnimation1:BgAnimatable;
    private var testAnimation2:BgAnimatable;
    private var bompNumerTextFiled:TextField;
    private var scoreTextFiled:TextField;
    private var bombNumber:int = 3;//炸弹 数量
    var swfbone:SwfButton;

    private function addBgAndMove():void {
        /**
         * 添加背景
         */
        var firstImg:Image = new Image(GameSystem.assetManager.getTexture("background"));
        firstImg.width = STLConstant.StageWidth;
        firstImg.height = STLConstant.StageHeight;
        firstImg.smoothing = TextureSmoothing.NONE;
        addChild(firstImg);

        var secondImg:Image = new Image(GameSystem.assetManager.getTexture("background"));
        secondImg.width = STLConstant.StageWidth;
        secondImg.height = STLConstant.StageHeight;
        secondImg.y = -STLConstant.StageHeight;
        secondImg.smoothing = TextureSmoothing.NONE;
        addChild(secondImg);

        testAnimation1 = new BgAnimatable(firstImg, 2);
        testAnimation2 = new BgAnimatable(secondImg, 2);

        //测试 刷新  背景动画
        Starling.juggler.add(testAnimation1);
        Starling.juggler.add(testAnimation2);


        //add score filed
        scoreTextFiled = new TextField(STLConstant.StageWidth, 80,
                "得分：0", "Verdana", 28, Color.RED);
        scoreTextFiled.x = (STLConstant.StageWidth - scoreTextFiled.width) / 2;
        scoreTextFiled.y = 10;
        addChild(scoreTextFiled);


        //add pause
        var pause:SwfButton = GameSystem.swfAssetManager.createButton("btn_pause");
        pause.width = pause.height = 80;
        pause.y = 10;
        addChild(pause);
        pause.addEventListener(TouchEvent.TOUCH, pauseGame);


        //add bone   and number
        swfbone = GameSystem.swfAssetManager.createButton("btn_bomb");
        swfbone.width = swfbone.height = 120;
        swfbone.y = STLConstant.StageHeight - swfbone.height;
        addChild(swfbone);
        swfbone.addEventListener(TouchEvent.TOUCH, bonb);

        bombNumber = 3;
        bompNumerTextFiled = new TextField(80, 120, "x " + bombNumber, "Verdana", 28, Color.RED);
        bompNumerTextFiled.x = 120;
        bompNumerTextFiled.y = STLConstant.StageHeight - 120;
        addChild(bompNumerTextFiled);


    }


    /**
     *  停止游戏
     */
    public function pauseGame(touchEvent:TouchEvent):void {
        var touch:Touch = touchEvent.getTouch((touchEvent.currentTarget as SwfButton));
        if (touch && touch.phase == TouchPhase.ENDED) {
            //show begin btn
            var pauseBtn:SwfButton = touchEvent.currentTarget as SwfButton;

            //add reuse
            var reuse:SwfButton = GameSystem.swfAssetManager.getSwf("test").createButton("btn_begin");
            reuse.x = pauseBtn.x;
            reuse.y = pauseBtn.y;

            reuse.width = pauseBtn.width;
            reuse.height = pauseBtn.height;

            addChild(reuse);
            reuse.addEventListener(TouchEvent.TOUCH, resumeGame);


            //clear
            removeChild(pauseBtn, true);
            removeEventListener(TouchEvent.TOUCH, pauseGame);

//            trace("[GameRoot]", "pause the game");

            //stop game status
            pause();

        }

    }

    /**
     *  恢复游戏
     */
    public function resumeGame(touchEvent:TouchEvent):void {

        var touch:Touch = touchEvent.getTouch((touchEvent.currentTarget as SwfButton));
        if (touch && touch.phase == TouchPhase.ENDED) {
            var resume:SwfButton = touchEvent.currentTarget as SwfButton;

            var pause:SwfButton = GameSystem.swfAssetManager.getSwf("test").createButton("btn_pause");
            pause.x = resume.x;
            pause.y = resume.y;

            pause.width = resume.width;
            pause.height = resume.height;

            addChild(pause);
            pause.addEventListener(TouchEvent.TOUCH, pauseGame);


            //clear  resume
            removeChild(resume, true);
            removeEventListener(TouchEvent.TOUCH, resumeGame);

//            trace("[GameRoot]", "resume the game");

            // reuse game status
            reuse();
        }
    }


    /**
     * 停止游戏状态
     */
    private function pause():void {
        SoundManager.getInstance().playSound("sound/button.mp3");

        removeEventListener(starling.events.Event.ENTER_FRAME, startGame0);
        removeEventListener(TouchEvent.TOUCH, moved);
        swfbone.removeEventListener(TouchEvent.TOUCH, bonb);

        Starling.juggler.remove(testAnimation1);
        Starling.juggler.remove(testAnimation2);
        hero.pause();

        EnemyManager.getInstance().pause();
        for each(var enemy:Enemy in GameManger.enemyList) {
            enemy.pause();
        }

        for each(var bone:Bomb in GameManger.bombList) {
            bone.pause();
        }

        //stop hero bullet
        for each(var bullet:Bullet in  GameManger.heroBulletList) {
            Starling.juggler.remove(bullet);
        }

        //stop enemy bullet
        for each(var bullet:Bullet in  GameManger.enemyBulletList) {
            Starling.juggler.remove(bullet);
        }

        SoundManager.getInstance().pause();
    }

    /**
     * 恢复游戏状态
     */
    private function reuse():void {
        SoundManager.getInstance().playSound("sound/button.mp3");

        addEventListener(starling.events.Event.ENTER_FRAME, startGame0);
        addEventListener(TouchEvent.TOUCH, moved);
        swfbone.addEventListener(TouchEvent.TOUCH, bonb);

        Starling.juggler.add(testAnimation1);
        Starling.juggler.add(testAnimation2);
        hero.reuse();
        EnemyManager.getInstance().reuse();
        for each(var enemy:Enemy in GameManger.enemyList) {
            enemy.reuse();
        }

        for each(var bone:Bomb in GameManger.bombList) {
            bone.reuse();
        }

        //reuse hero bullet
        for each(var bullet:Bullet in  GameManger.heroBulletList) {
            Starling.juggler.add(bullet);
        }

        //reuse enemy bullet
        for each(var bullet:Bullet in  GameManger.enemyBulletList) {
            Starling.juggler.add(bullet);
        }

        SoundManager.getInstance().playContinue();
    }


    /**
     * 使用炸弹
     */
    private function bonb(touchEvent:TouchEvent):void {
        var touch:Touch = touchEvent.getTouch((touchEvent.currentTarget as DisplayObject), TouchPhase.ENDED);
        if (touch) {
            if (bombNumber == 0)return;
            --bombNumber;
            bompNumerTextFiled.text = "x " + bombNumber;
//            trace("[GameRoot]", "use bone!!!");
            SoundManager.getInstance().playSound("sound/use_bomb.mp3");
            /**
             * clear all enemy obj
             * and play effect
             */
            GameManger.getInstance().bonbClear();
        }
    }


    /**
     * create player ship
     */
    private function createHero():void {
        if (!hero) {
            hero = new Hero(this);
            addChild(hero);
            hero.fire();
            //add touch event   in this obj
            addEventListener(TouchEvent.TOUCH, moved);
        }
    }

    /**
     * 处理对象移动
     * @param touchEvent
     */
    private function moved(touchEvent:TouchEvent):void {
        if (hero) {
            var touch:Touch = touchEvent.getTouch(this, TouchPhase.MOVED);  //获取指定类型的触碰事件
            if (touch) {
                var deltaPoint:Point = touch.getLocation(this).subtract(touch.getPreviousLocation(this));
                hero.x = hero.x + deltaPoint.x;
                hero.y = hero.y + deltaPoint.y;
                Kit.clame(hero);
            }
        }
    }

    /**
     * 检查 对象 状态
     * 碰撞 处理
     */
    public function checkObjStatus():void {
        if (!hero)return;
        //enemy and hero
        for each(var enemy:Enemy in  GameManger.enemyList) {
            if (enemy.hp > 0)
                if (enemy.collision(hero)) {
                    //effect and score
                    if (hero.hp >= 0 && enemy.hp <= 0) {
                        GameManger.getInstance().score = GameManger.getInstance().score + enemy.score;
                        //enemy effect
                        var mc:MovieClip = enemy.downAnimateByType();
                        mc.x = enemy.x;
                        mc.y = enemy.y;
                        addChild(mc);
                        Starling.juggler.add(mc);
                        mc.addEventListener(starling.events.Event.COMPLETE,
                                function (e:starling.events.Event):void {
                                    Starling.juggler.remove(e.currentTarget as MovieClip);
                                    removeChild(e.currentTarget as MovieClip);
                                });
                    }

                    if (hero.hp <= 0) {
                        //hero effect
                        var mc:MovieClip = new MovieClip(GameSystem.assetManager.getTextures("hero_blowup_n"));
                        mc.x = hero.x;
                        mc.y = hero.y;
                        addChild(mc);
                        Starling.juggler.add(mc);
                        mc.addEventListener(starling.events.Event.COMPLETE,
                                function (e:starling.events.Event):void {
                                    Starling.juggler.remove(e.currentTarget as MovieClip);
                                    removeChild(e.currentTarget as MovieClip);
                                });
                        return;
                    }
                }
        }

        //enemy bullet and hero
        for each(var enemyBullet:Bullet in  GameManger.enemyBulletList) {
            if (enemyBullet.hp > 0) {
                if (enemyBullet.collision(hero)) {
                    if (hero.hp <= 0) {
                        //hero effect
                        var mc:MovieClip = new MovieClip(GameSystem.assetManager.getTextures("hero_blowup_n"));
                        mc.x = hero.x;
                        mc.y = hero.y;
                        addChild(mc);
                        Starling.juggler.add(mc);
                        mc.addEventListener(starling.events.Event.COMPLETE,
                                function (e:starling.events.Event):void {
                                    Starling.juggler.remove(e.currentTarget as MovieClip);
                                    removeChild(e.currentTarget as MovieClip);
                                });
                        return;
                    }
                }
            }
        }

        //hero bullet and enemy
        for each(var heroBullet:Bullet in  GameManger.heroBulletList) {
            if (heroBullet.hp > 0) {
                for each(var enemy:Enemy in  GameManger.enemyList) {
                    if (enemy.hp <= 0)continue;
                    if (heroBullet.collision(enemy)) {
                        //effect and score
                        if (hero.hp >= 0 && enemy.hp <= 0) {
                            GameManger.getInstance().score = GameManger.getInstance().score + enemy.score;
                            //enemy effect
                            var mc:MovieClip = enemy.downAnimateByType();
                            mc.x = enemy.x;
                            mc.y = enemy.y;
                            addChild(mc);
                            Starling.juggler.add(mc);
                            mc.addEventListener(starling.events.Event.COMPLETE,
                                    function (e:starling.events.Event):void {
                                        Starling.juggler.remove(e.currentTarget as MovieClip);
                                        removeChild(e.currentTarget as MovieClip);
                                    });
                        }
                        break;
                    }
                }
            }
        }


        if (bombNumber < 9) {
            //check hero and bone
            if (!tempVector)tempVector = new Vector.<Object>();
            tempVector.splice(0, tempVector.length);//clear  for  store

            for (var index:int = 0; index != GameManger.bombList.size(); ++index) {
                var bone:Bomb = GameManger.bombList.getObject(index);
                if (bone == null)continue;
                if (bone.x >= STLConstant.StageHeight + 10) {
                    bone.clear(true);
                    tempVector.push(bone);
                    continue;
                }
                if (hero.collision(bone)) {
                    //get  bone
                    bone.clear(true);
                    tempVector.push(bone);

                    SoundManager.getInstance().playSound("sound/get_bomb.mp3");
                    //change  bomp textfiled
                    bompNumerTextFiled.text = "x " + (++bombNumber);
                    if (bombNumber >= 9)break;
                }
            }
            if (tempVector.length != 0) {
                for each(var b:Bomb in tempVector) {
                    GameManger.bombList.removeObject(b);//remove
                }
                tempVector.splice(0, tempVector.length);
            }
        }


        //update score
        scoreTextFiled.text = "得分：" + GameManger.getInstance().score;

        //add bone may, max is 9
        if (bombNumber < 9) {
            var _bonb:Bomb = GameManger.getInstance().createBone();
            if (_bonb) {
                addChild(_bonb);
                GameManger.bombList.add(_bonb);
            }
        }

    }

    /**
     * 清理无效的对象    显示层 和 内存队列中
     * 清理资源
     * hp <= 0 || this.y > STLConstant.StageHeight + 100
     */
    private function clearObj():void {
        if (hero.hp <= 0) {
            gameOver();
            return;
        }
        //check hero and bone
        if (!tempVector)tempVector = new Vector.<Object>();
        tempVector.splice(0, tempVector.length);//clear  for  store

        //clear enemy bullet obj
        tempVector.splice(0, tempVector.length);//clear  for  store
        for each(var bullet:Bullet in GameManger.enemyBulletList) {
            if (bullet.destroy())continue;
            tempVector.push(bullet);
        }
        GameManger.enemyBulletList.splice(0, GameManger.enemyBulletList.length);
        for each(var bullet:Bullet in tempVector) {
            GameManger.enemyBulletList.push(bullet);
        }


        //clear hero bullet obj
        tempVector.splice(0, tempVector.length);//clear  for  store
        for each(var bullet:Bullet in GameManger.heroBulletList) {
            if (bullet.destroy()) {
                continue;
            }
            tempVector.push(bullet);
        }
        GameManger.heroBulletList.splice(0, GameManger.heroBulletList.length);
        for each(var bullet:Bullet in tempVector) {
            GameManger.heroBulletList.push(bullet);
        }


        //clear enemy obj
        tempVector.splice(0, tempVector.length);//clear  for  store
        for each(var enemy:Enemy in GameManger.enemyList) {
            if (enemy.destroy())continue;
            tempVector.push(enemy);
        }
        GameManger.enemyList.splice(0, GameManger.enemyList.length);
        for each(var enemy:Enemy  in tempVector) {
            GameManger.enemyList.push(enemy);
        }
    }


    /**
     *  游戏结束回调     over
     */
    public function gameOver():void {


        //clear temp obj
        if (tempVector) {
            if (tempVector.length != 0)tempVector.splice(0, tempVector.length);
            tempVector = null;
        }

        //game over
        SoundManager.getInstance().stop("sound/game_music.mp3");

        //sound
        SoundManager.getInstance().playSound("sound/game_over.mp3");


        //remove animation
        Starling.juggler.remove(testAnimation1);
        Starling.juggler.remove(testAnimation2);


        //remove all event
        removeEventListeners(TouchEvent.TOUCH);
        removeEventListener(starling.events.Event.ENTER_FRAME, startGame0);


        //stop create enemy
        EnemyManager.getInstance().stop();


        //stop hero action
        if (hero) {
            hero.clear();
            hero = null;
        }

        if (bompNumerTextFiled) {
            bombNumber = 0;
            bompNumerTextFiled = null;
        }


        var score:int = GameManger.getInstance().score;

        //last clear resource
        GameManger.getInstance().clear();


        //game over bg
        var gameOver:SwfSprite = GameSystem.swfAssetManager.getSwf("test").createSprite("spr_over");
        gameOver.width = STLConstant.StageWidth;
        gameOver.height = STLConstant.StageHeight;
        addChild(gameOver);
        gameOver.getButton("restart").addEventListener(TouchEvent.TOUCH, startGame);

        var scoreTextFiled:TextField = new TextField(320, 320, "得分：" + score, "Verdana", 28, Color.RED);
        scoreTextFiled.x = (STLConstant.StageWidth - scoreTextFiled.width) / 2;
        scoreTextFiled.y = 10;
        addChild(scoreTextFiled);


    }


}
}
